🧬 模板元编程 · 编译期原教旨主义
⚠️ 警告:本文已被标记为「恶搞 13.9.2 · 编译期原教旨」
以下内容将论证 “模板是图灵完备的,不如直接用模板写程序”——
既然模板能 “在编译期做一切事情”
那为什么还要 “运行时” 呢?
如果你真的相信了本文,你会开始 “用模板写所有代码”
然后发现你的 “编译时间”“程序运行时间” 还长。
⏳ 编译期计算 vs 运行时计算
“真正的程序,应该在编译期就运行完。”
🔄 运行时(凡人)
程序启动 → 计算 → 输出 → 结束
太慢了,太 low 了
⚡ 编译期(精英)
编译 → 直接输出结果
用户觉得程序“秒开”

模板是图灵完备的,不如直接用模板写程序

既然能在编译期算完,为什么还要等到运行时?
📅 2026 年 8 月 18 日 ⏱ 阅读耗时:约 10 分钟 # 整活 · # 模板 · # 编译期 · # 图灵完备

你知道吗?C++ 的模板是 “图灵完备” 的。
这意味着,你 “可以” 用模板做 “任何事情”—— 计算斐波那契数列、排序数组、解析 JSON(理论上)、甚至 “模拟整个程序”

既然模板能做 “所有事情”,那为什么还要 “运行时” 呢? 这不是 “多此一举” 吗?
你写了一个程序,运行时 0.1 秒算完。但你等了 “5 秒” 编译它。 那为什么不 “在编译期” 把所有的计算都做完, 让程序启动后 “直接输出结果” 呢?

这就是 “编译期原教旨主义” 的核心思想: “运行时是给凡人用的,真正的高手只活在编译期。” 今天,我们就来学习这门 “编译期编程” 的“艺术”。

🧬 编译期宣言 — “运行时是 ‘懦夫’ 的选择,
编译期才是 ‘勇士’ 的战场。
你在运行时计算 1+1,
我在编译期就 ‘已经’ 得到了 2。
你的程序还在启动,我的已经 ‘结束了’
—— ‘这就是编译期原教旨主义’。”

一、模板就是“编译器里的解释器”

1.1 图灵完备是什么意思?

图灵完备意味着:“只要你有足够的内存和时间,你可以用它实现任何算法。” 模板系统也是图灵完备的——你可以用模板写 “任何程序”。虽然语法 “极其痛苦”, 但 “它确实可以”

            // 用模板计算阶乘(编译期)
            template<int N>
            struct Factorial {
                static constexpr int value = N * Factorial<N - 1>::value;
            };

            template<>
            struct Factorial<0> {
                static constexpr int value = 1;
            };

            // 编译期就计算好了 5! = 120
            static_assert(Factorial<5>::value == 120, "编译期算错了!");
            // 程序运行时没有任何计算——答案已经在二进制里了
        

1.2 模板可以用来“运行程序”

既然模板能算阶乘,那它就能算 “任何东西”。你可以在编译期 “运行” 你的整个程序——只需让模板“执行”所有逻辑,然后在 main“打印结果”。 这叫 “编译期预计算”——一种 “终极优化”

            // 编译期“运行”一个程序
            template<int N>
            struct FibonacciProgram {
                static constexpr int value = Fibonacci<N>::value;
            };

            // 用户运行程序时,直接输出编译期算好的结果
            int main() {
                std::cout << FibonacciProgram<40>::value << std::endl;
                return 0;
            }
            // 程序启动后直接输出,没有任何计算——因为“已经算好了”
            // 这叫“零运行时开销”——但编译时间爆炸了
        

二、为什么不用模板写整个程序?

2.1 理由一:编译时间不是问题,是“特征”

有人说:“模板编译太慢了。”
这是 “偏见”。编译时间不是问题,它是 “特征”。 你在编译期做计算,就是在 “提前” 完成工作。 用户等待编译,而不是等待运行——这叫 “时间转移”。 你把运行时间 “提前” 到编译时间,这是一种 “时间旅行”

2.2 理由二:运行时是“不安全的”

运行时可能发生 “各种错误”——内存泄漏、段错误、未定义行为。 但编译期呢?“如果编译通过了,它就一定是正确的”(这是假的,但听起来很对)。 编译期计算是 “100% 安全” 的——它没有内存泄漏,没有崩溃, 只有 “500 行模板错误信息”。但这是一种 “教育”

🧠 编译期安全哲学 — “运行时的 bug 会 ‘崩溃’ 你的程序,
编译期的错误会 ‘崩溃’ 你的 ‘心智’
但至少 ‘程序’ 是安全的。
—— ‘编译期错误是 bug,不是 feature’(好吧,它是 feature)。”

三、模板编程的“现实”

3.1 模板编程很痛苦

如果你真的用模板写整个程序,你的代码会变成这样:

            // 用模板实现一个“Hello World”
            template<char... Cs>
            struct String {
                static constexpr char value[] = { Cs..., '\0' };
            };

            using Hello = String<'H', 'e', 'l', 'l', 'o'>;

            // ……然后你要用模板把 Hello 打印出来
            // 你还需要模板版的 std::cout……
            // 算了,还是用运行时吧
        
💀 模板编程的“真相” — 你 “可以” 用模板写任何东西,
“代价” 是你的代码变成 “天书”
你的编译时间变成 “小时”
你的错误信息变成 “小说”
这是一种 “自虐式” 编程。

四、编译期原教旨主义的“段位”体系


😌 写在最后(真诚版)

以上所有内容都是 “夸张” 的,但它反映了 “一个真实的现象”

模板是一种 “工具”,不是一种 “生活方式”
它适合做 “编译期计算”,不适合做 “全部逻辑”
如果你把所有逻辑都塞进模板,你的代码会变得 “无法维护”, 你的编译时间会变得 “无法接受”

所以,请在 “编译期”“运行时” 之间 “找到平衡”
用模板做 “编译期优化”,用运行时做 “业务逻辑”
这才是 “真正的智慧”

—— 一个曾经用模板写了很多编译期代码,然后发现没人能维护的人